<template>
	<view class="recorder" @click="showPicker">
		<slot></slot>
		<view class="mask" @click.stop="toclose" v-if="isShow"></view>

		<view v-if="isShow" @click.stop="">
			<view class="lyview">
				<view class="image" v-if="beginRecoding"><image src="/static/yy.gif" mode="widthFix"></image></view>
				<view class="lyviewTop">
					<view class="lyviewTopLeft" @click="toclose">取消</view>
					<view class="lyviewTopRight" @click="confirm">确定</view>
				</view>

				<view class="lyviewCenter">
					<view class="lyviewCenterTop" @click="ontap"></view>
					<view class="lyviewCenterCenter">{{ nowDuration }}</view>
					<view class="lyviewCenterBottom">{{ beginRecoding ? '正在录音' : '点击开始录音' }}</view>
				</view>
			</view>
		</view>
	</view>
</template>
<script>
import Recorder from 'js-audio-recorder';
/**
 * @param isShow 是否显示音频录入组件
 * @param closeAudio 关闭音频录入组件或录音完毕的事件
 */
export default {
	data() {
		return {
			isShow: false,
			beginRecoding: false, // 开始录音
			blackBoxSpeak: false, // 是否上滑取消
			startY: '', // 手指滑动开始Y轴坐标
			timeOutEvent: 0, // 定时器
			waveCanvas: null,
			ctx: null,
			recorder: null, // 音频录入的实例
			drawRecordId: null, // 音频绘画波动图时的音频id
			nowDuration: '0:00', // 当前时长
			limitDuration: 60, // 限制时长，单位-秒
			drawColuList: [] // 录音时的柱状波动图，数据集合
		};
	},
	mounted() {
		// 创建录音实例
		this.recorder = new Recorder({
			sampleBits: 16, // 采样位数，支持 8 或 16，默认是16
			sampleRate: 48000, // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值
			numChannels: 1 // 声道，支持 1 或 2， 默认是1
			// compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换，默认是false
		});
		// 监听录音变化
		const vm = this;
		this.recorder.onprogress = function (params) {
			if (Math.floor(params.duration) === this.limitDuration) {
				vm.touchend();
			}
			let d = Math.floor(params.duration);
			d = Number(d) < 10 ? '0' + d : d;
			d = '0:' + d;
			vm.$set(vm, 'nowDuration', d);

			// console.log('--------------START---------------')
			// console.log('录音时长(秒)', params.duration);
			// console.log('录音大小(字节)', params.fileSize);
			// console.log('录音音量百分比(%)', params.vol);
			// console.log('当前录音的总数据([DataView, DataView...])', params.data);
			// console.log('--------------END---------------')
		};
	},
	methods: {
		showPicker() {
			this.isShow = true;
			this.$emit('show');
			this.getPermission();
		},
		ontap(e) {
			if (this.beginRecoding) {
				this.touchend(e);
			} else {
				this.touchstart(e);
			}
		},
		// 获取麦克风权限
		getPermission() {
			Recorder.getPermission().then(
				() => {
					console.log('录音给权限了');
				},
				(error) => {
					this.$msg(`${error.name}: ${error.message}`);
					console.log(`${error.name}: ${error.message}`);
				}
			);
		},
		// 手指开始触发
		touchstart(e) {
			this.blackBoxSpeak = true;
			this.startY = e.clientY;

			this.timeOutEvent = 0;
			// 长按1000毫秒后执行
			this.timeOutEvent = setTimeout(() => {
				this.startRecorder();
				this.beginRecoding = true;
			}, 500);
			return false;
		},
		toclose() {
			this.isShow = false;
			this.beginRecoding = false;
			this.$emit('closeAudio');
		},
		confirm() {
			this.isShow = false;
			this.beginRecoding = false;
			this.$emit('confirm', this.recorder.getWAVBlob());
			this.nowDuration = '0:00';
		},
		// 手指离开屏幕触发
		touchend() {
			// 清空定时器
			clearTimeout(this.timeOutEvent);
			if (this.timeOutEvent !== 0) {
				this.beginRecoding = false;
				this.stopRecorder(); // 停止录音
				// 长按结束调用保存录音或者返回录音数据
				if (this.blackBoxSpeak) {
					// 未上滑取消
					// this.$emit('closeAudio', this.recorder.getWAVBlob())
				}
				//console.log('松开>>>', this.getRecorder())
				// this.nowDuration = null;
				this.drawColuList = [];
			}
		},
		// 滑动触发
		touchmove(e) {
			const endY = e.clientY;
			this.blackBoxSpeak = this.startY < endY;
		},
		//长按超过x毫秒-- 开始录音
		startRecorder() {
			this.recorder.start().then(
				() => {
					this.beginRecoding = true;
				},
				(error) => {
					console.log(`${error.name} : ${error.message}`);
				}
			);
		},
		// 继续录音
		resumeRecorder() {
			this.recorder.resume();
		},
		// 暂停录音
		pauseRecorder() {
			this.recorder.pause();
			this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
			this.drawRecordId = null;
		},
		// 结束录音
		stopRecorder() {
			this.recorder.stop();
			this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
			this.drawRecordId = null;
		},
		// 录音播放
		playRecorder() {
			this.recorder.play();
			//this.drawPlay();//绘制波浪图
		},
		// 暂停录音播放
		pausePlayRecorder() {
			this.recorder.pausePlay();
		},
		// 恢复录音播放
		resumePlayRecorder() {
			this.recorder.resumePlay();
			//this.drawPlay();//绘制波浪图
		},
		// 停止录音播放
		stopPlayRecorder() {
			this.recorder.stopPlay();
		},
		// 销毁录音
		destroyRecorder() {
			const vm = this;
			if (vm.recorder) {
				vm.recorder.destroy().then(function () {
					vm.recorder = null;
					vm.drawRecordId && cancelAnimationFrame(vm.drawRecordId);
					vm.drawRecordId = null;
				});
			}
		},
		// 获取录音文件
		getRecorder() {
			let map = new Map();
			map.set('duration', this.recorder.duration); //录音总时长
			map.set('fileSize', this.recorder.fileSize); //录音总大小
			//录音结束，获取取录音数据
			map.set('PCMBlob', this.recorder.getPCMBlob()); //获取 PCM 数据
			map.set('wavBlob', this.recorder.getWAVBlob()); //获取 WAV 数据
			map.set('channel', this.recorder.getChannelData()); //获取左声道和右声道音频数据
			return map;
		},
		// 下载pcm格式
		downPCM() {
			this.recorder.downloadPCM('新文件'); //这里传参进去的时文件名
		},
		// 下载wav格式
		downWAV() {
			this.recorder.downloadWAV('新文件'); //这里传参进去的时文件名
		},
		// 销毁实例
		beforeDestroy() {
			this.destroyRecorder();
		}
	}
};
</script>
<style lang="scss">
.mask {
	position: fixed;
	z-index: 1000;
	top: 0;
	right: 0;
	left: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.6);
}

.lyview {
	height: 540rpx;
	width: 100%;
	position: fixed;
	left: 0;
	bottom: 0;
	background-color: #fff;
	padding: 0 20rpx;
	z-index: 1001;

	.image {
		position: absolute;
		left: 50%;
		top: -400rpx;
		margin-left: -200rpx;
		width: 400rpx;
	}

	.lyviewTop {
		display: flex;
		align-items: center;
		padding: 20rpx 40rpx;
		font-size: 14px;

		.lyviewTopLeft {
			flex: 1;
			text-align: left;
			color: #666;
		}

		.lyviewTopRight {
			flex: 1;
			text-align: right;
			color: #d0021b;
		}
	}

	.lyviewCenter {
		padding: 54rpx 0;
		text-align: center;

		.lyviewCenterTop {
			position: relative;
			margin: 0 auto;
			// left: 270rpx;
			width: 172rpx;
			height: 172rpx;
			background: url('~@/static/ly.png') no-repeat 100% 100%;
		}

		.lyviewCenterCenter {
			font-size: 16px;
			padding: 20rpx 0 15rpx 0;
			color: #333;
		}

		.lyviewCenterBottom {
			font-size: 16px;
			padding: 10rpx 0 15rpx 0;
			color: #333;
		}
	}
}
</style>
